package com.datahandlers;

import com.gui.helper.CustomTableModel;
import com.gui.helper.CustomerModel;
import com.inventory.controllers.CustomerControllerRemote;
import com.inventory.controllers.CustomerDetailsControllerRemote;
import com.inventory.entities.Customer;
import com.inventory.entities.CustomerDetails;
import com.util.ResourceLoader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Handles the data and the user interface actions for the CustomerDetails and
 * Customer_Details relations in the database.
 * @author sithum
 */
public class CustomerDataHandler implements DataHandler {

    private List<Customer> customerList;
    private List<CustomerDetails> detailsList;
    private String[] tableHeaders = new String[]{ResourceLoader.getInstance().getProperty("customer.column0"), ResourceLoader.getInstance().getProperty("customer.column1"),
        ResourceLoader.getInstance().getProperty("customer.column2"), ResourceLoader.getInstance().getProperty("customer.column3"),
        ResourceLoader.getInstance().getProperty("customer.column4"), ResourceLoader.getInstance().getProperty("customer.column5"),
        ResourceLoader.getInstance().getProperty("customer.column6"), ResourceLoader.getInstance().getProperty("customer.column7"),
        ResourceLoader.getInstance().getProperty("customer.column8"), new String()};
    private CustomTableModel model;
    private Object[][] tableData;
    private CustomerControllerRemote controller;
    private CustomerDetailsControllerRemote detailsController;
    private String[] routeNames;
    private List<Customer> data;
    private static int customerCount = 0;
    private static int detailsCount = 0;

    public CustomerDataHandler(CustomerControllerRemote controller, CustomerDetailsControllerRemote detailsController) {
        try {
            this.detailsController = detailsController;
            this.init(controller);
        } catch (Exception ex) {
            Logger.getLogger(CustomerDataHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void init(Object controller) throws Exception {
        this.controller = (CustomerControllerRemote) controller;
        customerList = new ArrayList<Customer>();
        detailsList = new ArrayList<CustomerDetails>();
        this.processData();
        model = new CustomTableModel(tableHeaders, tableData);
        customerCount = this.controller.count();
        detailsCount = this.detailsController.count();
    }

    public void addRecord(Object object) {
        Customer customer = new Customer();
        CustomerDetails details = new CustomerDetails();
        CustomerModel customerModel = (CustomerModel) object;
        customer.setCustomerId(++customerCount);
        customer.setCustomerName(customerModel.getName());
        customer.setShopName(customerModel.getShop());
        details.setDetailsId(++detailsCount);
        details.setCustomerContact(customerModel.getTelephone());
        details.setCustomerMobile(customerModel.getMobile());
        details.setCustomerId(customer);
        details.setRouteId(customerModel.getRoute());
        details.setShopAddress(customerModel.getAddress());
        if ((customerModel.getDiscountAmount() != null) && !(customerModel.getDiscountAmount().equals(""))) {
            customer.setDiscountAmount(customerModel.getDiscount(customerModel.getDiscountAmount()));
        }
        if ((customerModel.getDiscountPercentage() != null) && !(customerModel.getDiscountPercentage().equals(""))) {
            customer.setDiscountPercentage(customerModel.getDiscount(customerModel.getDiscountPercentage()));
        }
        this.detailsList.add(details);
        customer.setCustomerDetailsCollection(detailsList);
        this.customerList.add(customer);
    }

    public void addEditRecord(Object key, Object value) {
        Customer c = new Customer();
        c.setCustomerId(new Integer(key.toString()));
        Customer customer = controller.findByCustomerId(c);
        CustomerDetails details = customer.getCustomerDetailsCollection().get(0);
        CustomerModel customerModel = (CustomerModel) value;
        customer.setCustomerName(customerModel.getName());
        customer.setShopName(customerModel.getShop());
        details.setCustomerContact(customerModel.getTelephone());
        details.setCustomerMobile(customerModel.getMobile());
        details.setCustomerId(customer);
        details.setRouteId(customerModel.getRoute());
        details.setShopAddress(customerModel.getAddress());
        if ((customerModel.getDiscountAmount() != null) && !(customerModel.getDiscountAmount().equals(""))) {
            customer.setDiscountAmount(customerModel.getDiscount(customerModel.getDiscountAmount()));
            customer.setDiscountPercentage(null);
        }
        if ((customerModel.getDiscountPercentage() != null) && !(customerModel.getDiscountPercentage().equals(""))) {
            customer.setDiscountPercentage(customerModel.getDiscount(customerModel.getDiscountPercentage()));
            customer.setDiscountAmount(null);
        }
        this.detailsList.add(details);
        customer.setCustomerDetailsCollection(detailsList);
        this.customerList.add(customer);
    }

    public void editData() throws Exception {
        controller.edit(customerList, detailsList);
        customerList.clear();
        detailsList.clear();
    }

    public void saveData() throws Exception {
        controller.create(customerList, detailsList);
        customerList.clear();
        detailsList.clear();
        this.processData();
    }

    public CustomTableModel getModel() {
        return this.model;
    }

    public boolean temporaryStorageEmpty() {
        return customerList.isEmpty();
    }

    public boolean tempEditStorageEmpty() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     * Process the data retrived from the database to display in a JTable.
     * @return java.lang.Object[][]
     * @throws java.lang.Exception
     */
    private void processData() throws Exception {
        this.setData(controller.findAll());
        this.processData(this.getData());
    }

    private void processData(List<Customer> data) {
        Object[][] dataSet = new Object[data.size()][10];
        String[] names = new String[data.size()];
        int index = 0;
        for (Customer customer : data) {
            CustomerDetails details = customer.getCustomerDetailsCollection().get(0);
            dataSet[index][0] = customer.getCustomerId();
            dataSet[index][1] = customer.getCustomerName();
            dataSet[index][2] = customer.getShopName();
            dataSet[index][3] = details.getCustomerContact();
            dataSet[index][4] = details.getCustomerMobile();
            dataSet[index][5] = details.getShopAddress();
            dataSet[index][6] = details.getRouteId().getRouteName();
            if (customer.getDiscountAmount() != null) {
                dataSet[index][7] = customer.getDiscountAmount();
                dataSet[index][8] = "";
            } else {
                dataSet[index][7] = "";
                dataSet[index][8] = customer.getDiscountPercentage();
            }
            dataSet[index][9] = new Boolean(false);
            index++;
        }
        this.setTableData(dataSet);
    }

    public List<Customer> getCustomerList() {
        return customerList;
    }

    public void setCustomerList(List<Customer> customerList) {
        this.customerList = customerList;
    }

    public List<Customer> getData() {
        return data;
    }

    public void setData(List<Customer> data) {
        this.data = data;
    }

    public List<CustomerDetails> getDetailsList() {
        return detailsList;
    }

    public void setDetailsList(List<CustomerDetails> detailsList) {
        this.detailsList = detailsList;
    }

    public String[] getRouteNames() {
        return routeNames;
    }

    public void setRouteNames(String[] routeNames) {
        this.routeNames = routeNames;
    }

    public Object[][] getTableData() {
        return tableData;
    }

    public void setTableData(Object[][] tableData) {
        this.tableData = tableData;
    }

    public String[] getTableHeaders() {
        return tableHeaders;
    }

    public void setTableHeaders(String[] tableHeaders) {
        this.tableHeaders = tableHeaders;
    }
}
